package com.example.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.bo.ArticleTagRelBO;
import com.example.dto.*;
import com.example.entity.Archives;
import com.example.entity.Article;
import com.example.entity.Category;
import com.example.entity.Tag;
import com.example.handlers.BaseContext;
import com.example.mapper.ArticleMapper;
import com.example.mapper.CategoryMapper;
import com.example.service.ArchivesService;
import com.example.service.ArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.service.CategoryService;
import com.example.vo.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.config.TencentCosConfig;
import java.util.Calendar;


import java.util.ArrayList;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

/**
 * <p>
 * 文章表 服务实现类
 * </p>
 *
 * @author wuyunbin
 * @since 2024-10-19
 */
@Slf4j
@Service
@Transactional
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private CategoryService categoryService;

    @Resource
    private TencentCosConfig tencentCosConfig;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private ArchivesService archivesService;

    @Override
    public void publish(ArticlePublishDTO articlePublishDTO) {
        Article article = new Article();
        BeanUtil.copyProperties(articlePublishDTO, article);
        // 获取线程变量
        Integer userId = BaseContext.getCurrentId();
        article.setUserId(userId);
        this.save(article);
        //存储标签信息
        List<Integer> tags = articlePublishDTO.getTags();
        List<ArticleTagRelBO> boList = new ArrayList<>();
        for (Integer tag : tags) {
            ArticleTagRelBO articleTagRelBO = new ArticleTagRelBO();
            articleTagRelBO.setArticleId(article.getId());
            articleTagRelBO.setTagId(tag);
            boList.add(articleTagRelBO);
        }
        articleMapper.saveArticleTagRel(boList);

        // 2. 添加归档记录
        Archives archive = new Archives();
        archive.setTitle(article.getTitle());
        // 根据 categoryId 查询分类名称
        Category category = categoryMapper.selectById(article.getCategoryId());
        if (category != null) {
            archive.setCategory(category.getName());
        } else {
            archive.setCategory("默认分类");
        }
        // 使用文章的创建时间作为归档时间
        Date now = new Date();
        archive.setCreatedAt(now);
        archive.setUpdatedAt(now);
        // 计算年份和月份
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        archive.setYear(calendar.get(Calendar.YEAR));
        int month = calendar.get(Calendar.MONTH) + 1;
        archive.setMonth(String.format("%02d", month));

        // 保存归档记录
        archive.setUserId(userId);
        boolean archiveSaved = archivesService.save(archive);
        log.info("Archive save result: {}", archiveSaved);

    }

    @Override
    public IPage<ArticlePageVO> getPage(ArticlePageDTO articlePageDTO) {
        IPage<Article> pageInfo = new Page<>(articlePageDTO.getCurrent(), articlePageDTO.getSize());
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        
        // 添加标题模糊搜索条件
        if (articlePageDTO.getSearchTitle() != null && !articlePageDTO.getSearchTitle().isEmpty()) {
            wrapper.like(Article::getTitle, articlePageDTO.getSearchTitle());
            log.info("添加标题搜索条件: {}", articlePageDTO.getSearchTitle());
        }
        
        // 添加日期条件
        if (articlePageDTO.getStartDate() != null) {
            wrapper.ge(Article::getCreateTime, articlePageDTO.getStartDate());
        }
        
        if (articlePageDTO.getEndDate() != null) {
            wrapper.le(Article::getCreateTime, articlePageDTO.getEndDate());
        }
        
        wrapper.orderByDesc(Article::getCreateTime);
        IPage<Article> page = this.page(pageInfo, wrapper);

        // 转换为VO对象
        IPage<ArticlePageVO> voPage = new Page<>();
        List<ArticlePageVO> voList = new ArrayList<>();

        for (Article article : page.getRecords()) {
            ArticlePageVO vo = new ArticlePageVO();
            BeanUtil.copyProperties(article, vo);

            // 获取分类信息
            Category category = categoryService.getById(article.getCategoryId());
            if (category != null) {
                vo.setCategoryName(category.getName());
            }

            // 获取标签信息
            List<Tag> tags = articleMapper.getTagListByArticleId(article.getId());
            vo.setTags(tags);

            // 手动设置 cover 字段，对应 Article 中的 titleImage 字段
            String titleImage = article.getTitleImage();
            if (titleImage != null && !titleImage.isEmpty()) {
                // 如果URL不是以http开头，则添加前缀
                if (!titleImage.startsWith("http://") && !titleImage.startsWith("https://")) {
                    titleImage = tencentCosConfig.getBaseUrl() + (tencentCosConfig.getBaseUrl().endsWith("/") ? "" : "/") + titleImage;
                }
                vo.setCover(titleImage);
                log.info("设置文章列表封面 - ID: {}, 最终URL: {}", article.getId(), titleImage);
            } else {
                // 不设置默认图片，前端会处理
                vo.setCover("");
                log.info("文章列表无封面 - ID: {}", article.getId());
            }

            voList.add(vo);
        }

        voPage.setRecords(voList);
        voPage.setTotal(page.getTotal());
        voPage.setCurrent(page.getCurrent());
        voPage.setSize(page.getSize());

        return voPage;
    }

    @Override
    public void removeArticle(ArticleDeleteDTO articleDeleteDTO) {
        this.removeById(articleDeleteDTO.getArticleId());
        articleMapper.removeArticleTagTel(articleDeleteDTO.getArticleId());
    }

    @Override
    public ArticleDetailVO detail(ArticleDetailDTO articleDetailDTO) {
        Article article = this.getById(articleDetailDTO.getArticleId());

        ArticleDetailVO articleDetailVO = new ArticleDetailVO();
        BeanUtil.copyProperties(article, articleDetailVO);

        // 处理封面URL
        String titleImage = article.getTitleImage();
        if (titleImage != null && !titleImage.isEmpty()) {
            // 如果URL不是以http开头，则添加前缀
            if (!titleImage.startsWith("http://") && !titleImage.startsWith("https://")) {
                titleImage = tencentCosConfig.getBaseUrl() + (tencentCosConfig.getBaseUrl().endsWith("/") ? "" : "/") + titleImage;
            }
            articleDetailVO.setCover(titleImage);
            log.info("设置文章封面 - ID: {}, 最终URL: {}", article.getId(), titleImage);
        } else {
            // 不设置默认图片，前端会处理
            articleDetailVO.setCover("");
            log.info("文章无封面 - ID: {}", article.getId());
        }

        articleDetailVO.setSummary(article.getDescription());

        List<Integer> tagIds = articleMapper.getTagIdsByArticleId(articleDetailDTO.getArticleId());
        articleDetailVO.setTagIds(tagIds);

        log.info("文章详情 - ID: {}, 标题: {}", article.getId(), article.getTitle());

        return articleDetailVO;
    }

    @Override
    public void updateArticle(ArticlePublishDTO articlePublishDTO) {
//        将前端传过来的数据转化成后端实体对象
        Article article = new Article();
        // 将articlePublishDTO中的属性值复制到新创建的article对象中（hutool）
        BeanUtil.copyProperties(articlePublishDTO, article);

        // 打印article对象
        log.info("article:{}", article);
        // 调用本类updateById方法更新数据,传入的是article实体类
        this.updateById(article);
        //按照文章id删除标签关联
        articleMapper.removeArticleTagTel(article.getId());

//        存储新的关联关系
//        存储标签信息
        // 从ArticlePublishDTO中获取前端给的整型标签列表tags
        List<Integer> tags = articlePublishDTO.getTags();
        // 初始化一个新的ArrayList，用来后端存储ArticleTagRelBO业务对象
        List<ArticleTagRelBO> boList = new ArrayList<>();
        // 遍历标签列表tags
        for (Integer tag : tags) {
            // 初始化一个ArticleTagRelBO对象，用来存储articleId和tagId
            ArticleTagRelBO articleTagRelBO = new ArticleTagRelBO();
            // 将当前文章的id传给articleTagRelBO对象里的articleId属性
            articleTagRelBO.setArticleId(article.getId());
            // 将前端传过来的tags一一赋值给ArticleTagRelBO对象的tagId属性
            articleTagRelBO.setTagId(tag);
            // 每处理完一个标签Id，就会有一个新的ArticleTagRelBO对象加入到boList中
            boList.add(articleTagRelBO);
        }
        // 将boList中的数据批量存入数据库
        articleMapper.saveArticleTagRel(boList);
    }

    @Override
    public ArticleDetailVO4Web getArticleDetail(ArticleDetailDTO articleDetailDTO) {
        if (articleDetailDTO == null || articleDetailDTO.getArticleId() == null) {
            log.error("获取文章详情失败 - 文章ID为空");
            return null;
        }

        // 查询文章
        Article article = this.getById(articleDetailDTO.getArticleId());

        // 检查文章是否存在
        if (article == null) {
            log.error("获取文章详情失败 - 文章不存在，ID: {}", articleDetailDTO.getArticleId());
            return null;
        }

        // 创建响应对象
        ArticleDetailVO4Web articleDetailVO4Web = new ArticleDetailVO4Web();

        // 数据对拷，article属性拷贝给articleDetailVO4Web
        BeanUtil.copyProperties(article, articleDetailVO4Web);
        
        // 确保点赞数被正确设置
        articleDetailVO4Web.setLikeCount(article.getLikeCount() != null ? article.getLikeCount() : 0);
        
        // 确保收藏数被正确设置
        articleDetailVO4Web.setFavoriteCount(article.getFavoriteCount() != null ? article.getFavoriteCount() : 0);

        // 获取分类信息
        if (article.getCategoryId() != null) {
            Category category = categoryService.getById(article.getCategoryId());
            if (category != null) {
                articleDetailVO4Web.setCategoryName(category.getName());
            } else {
                articleDetailVO4Web.setCategoryName("未分类");
                log.warn("文章的分类不存在 - 文章ID: {}, 分类ID: {}", article.getId(), article.getCategoryId());
            }
        } else {
            articleDetailVO4Web.setCategoryName("未分类");
        }

        // 获取上下文章
        try {
            // 获取后一篇文章
            NextArticle nextArticle = this.getNextArticle(article.getId());
            articleDetailVO4Web.setNextArticle(nextArticle);

            // 获取前一篇文章
            PreArticle preArticle = this.getPreArticle(article.getId());
            articleDetailVO4Web.setPreArticle(preArticle);
        } catch (Exception e) {
            log.error("获取文章上下文失败 - 文章ID: {}, 错误: {}", article.getId(), e.getMessage());
            // 避免因为上下文获取失败而影响整个请求
            articleDetailVO4Web.setNextArticle(null);
            articleDetailVO4Web.setPreArticle(null);
        }

        // 获取标签列表
        try {
            List<Tag> tags = articleMapper.getTagListByArticleId(article.getId());
            articleDetailVO4Web.setTags(tags != null ? tags : new ArrayList<>());
        } catch (Exception e) {
            log.error("获取文章标签失败 - 文章ID: {}, 错误: {}", article.getId(), e.getMessage());
            articleDetailVO4Web.setTags(new ArrayList<>());
        }

        // 处理封面URL
        String titleImage = article.getTitleImage();
        if (titleImage != null && !titleImage.isEmpty()) {
            // 如果URL不是以http开头，则添加前缀
            if (!titleImage.startsWith("http://") && !titleImage.startsWith("https://")) {
                titleImage = tencentCosConfig.getBaseUrl() + (tencentCosConfig.getBaseUrl().endsWith("/") ? "" : "/") + titleImage;
            }
            articleDetailVO4Web.setCover(titleImage);
            log.info("设置文章封面 - ID: {}, 最终URL: {}", article.getId(), titleImage);
        } else {
            // 不设置默认图片，前端会处理
            articleDetailVO4Web.setCover("");
            log.info("文章无封面 - ID: {}", article.getId());
        }

        return articleDetailVO4Web;
    }

//    @Override
//    public ArticleDetailVO4Web getArticlePreview(ArticleDetailDTO articleDetailDTO) {
//        ArticleDetailVO4Web preview = new ArticleDetailVO4Web();
//
//        Article article = this.getById(articleDetailDTO.getArticleId());
//        if (article == null) {
//            return preview;
//        }
//
//        // 复制基础属性
//        BeanUtil.copyProperties(article, preview);
//
//        // 获取分类名称
//        Category category = categoryService.getById(article.getCategoryId());
//        if (category != null) {
//            preview.setCategoryName(category.getName());
//        }
//
//        // 获取标签
//        List<Tag> tags = articleMapper.getTagListByArticleId(article.getId());
//        preview.setTags(tags);
//
//        // 处理封面URL
//        String titleImage = article.getTitleImage();
//        if (titleImage != null && !titleImage.isEmpty()) {
//            // 如果URL不是以http开头，则添加前缀
//            if (!titleImage.startsWith("http://") && !titleImage.startsWith("https://")) {
//                titleImage = tencentCosConfig.getBaseUrl() + (tencentCosConfig.getBaseUrl().endsWith("/") ? "" : "/") + titleImage;
//            }
//            preview.setCover(titleImage);
//            log.info("设置文章预览封面 - ID: {}, 最终URL: {}", article.getId(), titleImage);
//        } else {
//            preview.setCover("");
//        }
//
//        // 返回简化版的内容（只取前300个字符）
//        String content = article.getContent();
//        if (content != null && content.length() > 300) {
//            preview.setContent(content.substring(0, 300) + "...");
//        }
//
//        log.info("获取文章预览 - ID: {}, 标题: {}", article.getId(), article.getTitle());
//        return preview;
//    }

    @Override
    public IPage<ArticlePageVO> getPageByUserId(ArticlePageDTO articlePageDTO) {
        // 获取线程变量
        Integer userId = BaseContext.getCurrentId();
        articlePageDTO.setUserId(userId);

        IPage<Article> pageInfo = new Page<>(articlePageDTO.getCurrent(), articlePageDTO.getSize());
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getUserId, articlePageDTO.getUserId());
        
        // 添加标题模糊搜索条件
        if (articlePageDTO.getSearchTitle() != null && !articlePageDTO.getSearchTitle().isEmpty()) {
            wrapper.like(Article::getTitle, articlePageDTO.getSearchTitle());
            log.info("用户文章列表添加标题搜索条件: {}", articlePageDTO.getSearchTitle());
        }
        
        // 添加日期条件
        if (articlePageDTO.getStartDate() != null) {
            wrapper.ge(Article::getCreateTime, articlePageDTO.getStartDate());
        }
        
        if (articlePageDTO.getEndDate() != null) {
            wrapper.le(Article::getCreateTime, articlePageDTO.getEndDate());
        }
        
        wrapper.orderByDesc(Article::getCreateTime);
        IPage<Article> page = this.page(pageInfo, wrapper);

        // 转换为VO对象
        IPage<ArticlePageVO> voPage = new Page<>();
        List<ArticlePageVO> voList = new ArrayList<>();

        for (Article article : page.getRecords()) {
            ArticlePageVO vo = new ArticlePageVO();
            BeanUtil.copyProperties(article, vo);

            // 获取分类信息
            Category category = categoryService.getById(article.getCategoryId());
            if (category != null) {
                vo.setCategoryName(category.getName());
            }

            // 获取标签信息
            List<Tag> tags = articleMapper.getTagListByArticleId(article.getId());
            vo.setTags(tags);

            // 手动设置 cover 字段，对应 Article 中的 titleImage 字段
            String titleImage = article.getTitleImage();
            if (titleImage != null && !titleImage.isEmpty()) {
                // 如果URL不是以http开头，则添加前缀
                if (!titleImage.startsWith("http://") && !titleImage.startsWith("https://")) {
                    titleImage = tencentCosConfig.getBaseUrl() + (tencentCosConfig.getBaseUrl().endsWith("/") ? "" : "/") + titleImage;
                }
                vo.setCover(titleImage);
                log.info("设置文章列表封面 - ID: {}, 最终URL: {}", article.getId(), titleImage);
            } else {
                // 不设置默认图片，前端会处理
                vo.setCover("");
                log.info("文章列表无封面 - ID: {}", article.getId());
            }

            voList.add(vo);
        }

        voPage.setRecords(voList);
        voPage.setTotal(page.getTotal());
        voPage.setCurrent(page.getCurrent());
        voPage.setSize(page.getSize());

        return voPage;
    }

    @Override
    public Integer getArticleCount() {
        // 获取线程变量
        Integer userId = BaseContext.getCurrentId();
        return articleMapper.getArticleById(userId);
    }

    @Override
    public List<CategoryDistributionVO> getCategoryDistribution() {
        // 获取当前用户ID (从BaseContext获取的是admin_id)
        Integer adminId = BaseContext.getCurrentId();
        if (adminId == null) {
            log.error("获取用户文章分类分布时用户ID为空");
            return new ArrayList<>();
        }
        
        log.info("获取用户文章分类分布 - 管理员ID: {}", adminId);
        
        // 查询文章表，使用adminId作为userId
        // 注意：文章表里面的userId对应的是tb_admin里面的id
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getUserId, adminId);
        List<Article> userArticles = this.list(wrapper);
        
        if (userArticles == null || userArticles.isEmpty()) {
            log.info("用户(管理员ID: {}) 没有发布任何文章", adminId);
            return new ArrayList<>();
        }
        
        log.info("用户(管理员ID: {}) 发布了 {} 篇文章", adminId, userArticles.size());
        
        // 获取所有分类
        List<Category> allCategories = categoryService.list();
        Map<Integer, String> categoryMap = new HashMap<>();
        for (Category category : allCategories) {
            categoryMap.put(category.getId(), category.getName());
        }
        
        // 统计每个分类下的文章数量
        Map<Integer, Integer> categoryCountMap = new HashMap<>();
        for (Article article : userArticles) {
            Integer categoryId = article.getCategoryId();
            categoryCountMap.put(categoryId, categoryCountMap.getOrDefault(categoryId, 0) + 1);
        }
        
        // 转换为前端需要的格式
        List<CategoryDistributionVO> result = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : categoryCountMap.entrySet()) {
            Integer categoryId = entry.getKey();
            Integer count = entry.getValue();
            
            CategoryDistributionVO vo = new CategoryDistributionVO();
            vo.setName(categoryMap.getOrDefault(categoryId, "未分类"));
            vo.setValue(count);
            
            log.info("分类: {}, 文章数: {}", vo.getName(), vo.getValue());
            result.add(vo);
        }
        
        log.info("用户(管理员ID: {}) 文章分类分布统计结果: {} 个分类", adminId, result.size());
        
        // 如果没有任何分类，返回一个默认的"暂无数据"分类
        if (result.isEmpty()) {
            CategoryDistributionVO vo = new CategoryDistributionVO();
            vo.setName("暂无数据");
            vo.setValue(0);
            result.add(vo);
        }
        
        return result;
    }

    public NextArticle getNextArticle(Integer currentId) {
        // 防止无限循环的最大迭代次数
        int maxIterations = 100;
        int iterations = 0;
        Integer nextId = currentId + 1;
        Integer maxId = articleMapper.getMaxId();

        // 如果当前ID已经是最大ID，则不会有下一篇
        if (currentId >= maxId) {
            return null;
        }

        while (iterations < maxIterations) {
            Article article = this.getById(nextId);
            if (article != null) {
                NextArticle nextArticle = new NextArticle();
                nextArticle.setArticleId(article.getId());
                nextArticle.setArticleTitle(article.getTitle());
                return nextArticle;
            }

            // 如果已经超过最大ID，则不会有下一篇
            if (nextId > maxId) {
                return null;
            }

            // 尝试下一个ID
            nextId++;
            iterations++;
        }

        log.warn("获取下一篇文章超过最大迭代次数，可能存在数据问题。当前文章ID: {}", currentId);
        return null;
    }

    public PreArticle getPreArticle(Integer currentId) {
        // 防止无限循环的最大迭代次数
        int maxIterations = 100;
        int iterations = 0;
        Integer prevId = currentId - 1;
        Integer minId = articleMapper.getMinId();

        // 如果当前ID已经是最小ID，则不会有上一篇
        if (currentId <= minId) {
            return null;
        }

        while (iterations < maxIterations) {
            Article article = this.getById(prevId);
            if (article != null) {
                PreArticle preArticle = new PreArticle();
                preArticle.setArticleId(article.getId());
                preArticle.setArticleTitle(article.getTitle());
                return preArticle;
            }

            // 如果已经低于最小ID，则不会有上一篇
            if (prevId < minId) {
                return null;
            }

            // 尝试上一个ID
            prevId--;
            iterations++;
        }

        log.warn("获取上一篇文章超过最大迭代次数，可能存在数据问题。当前文章ID: {}", currentId);
        return null;
    }

    @Override
    public IPage<ArticlePageVO> getCategoryArticles(ArticlePageDTO articlePageDTO) {
        IPage<Article> pageInfo = new Page<>(articlePageDTO.getCurrent(), articlePageDTO.getSize());
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        // 按分类ID筛选文章，只有当categoryId不为空时才添加条件
        if (articlePageDTO.getCategoryId() != null) {
            wrapper.eq(Article::getCategoryId, articlePageDTO.getCategoryId());
        }
        // 按创建时间降序排序
        wrapper.orderByDesc(Article::getCreateTime);
        IPage<Article> page = this.page(pageInfo, wrapper);

        // 转换为VO对象
        IPage<ArticlePageVO> voPage = new Page<>();
        List<ArticlePageVO> voList = new ArrayList<>();

        for (Article article : page.getRecords()) {
            ArticlePageVO vo = new ArticlePageVO();
            BeanUtil.copyProperties(article, vo);

            // 获取分类信息
            Category category = categoryService.getById(article.getCategoryId());
            if (category != null) {
                vo.setCategoryName(category.getName());
            }

            // 获取标签信息
            List<Tag> tags = articleMapper.getTagListByArticleId(article.getId());
            vo.setTags(tags);

            // 手动设置 cover 字段，对应 Article 中的 titleImage 字段
            String titleImage = article.getTitleImage();
            if (titleImage != null && !titleImage.isEmpty()) {
                // 如果URL不是以http开头，则添加前缀
                if (!titleImage.startsWith("http://") && !titleImage.startsWith("https://")) {
                    titleImage = tencentCosConfig.getBaseUrl() + (tencentCosConfig.getBaseUrl().endsWith("/") ? "" : "/") + titleImage;
                }
                vo.setCover(titleImage);
                log.info("设置分类文章列表封面 - ID: {}, 最终URL: {}", article.getId(), titleImage);
            } else {
                // 不设置默认图片，前端会处理
                vo.setCover("");
                log.info("分类文章列表无封面 - ID: {}", article.getId());
            }

            voList.add(vo);
        }

        voPage.setRecords(voList);
        voPage.setTotal(page.getTotal());
        voPage.setCurrent(page.getCurrent());
        voPage.setSize(page.getSize());

        return voPage;
    }

    @Override
    public IPage<ArticlePageVO> getTagArticles(ArticlePageDTO articlePageDTO) {
        // 创建分页对象
        IPage<Article> pageInfo = new Page<>(articlePageDTO.getCurrent(), articlePageDTO.getSize());
        
        // 获取标签ID对应的文章列表
        if (articlePageDTO.getTagId() == null) {
            log.error("获取标签文章列表时标签ID为空");
            return new Page<>(); // 返回空分页
        }
        
        // 获取与该标签关联的所有文章ID
        List<Integer> articleIds = articleMapper.getArticleIdsByTagId(articlePageDTO.getTagId());
        
        if (articleIds == null || articleIds.isEmpty()) {
            log.info("标签ID {} 下没有关联的文章", articlePageDTO.getTagId());
            return new Page<>(); // 返回空分页
        }
        
        // 构建查询条件
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Article::getId, articleIds)
               .orderByDesc(Article::getCreateTime);
        
        // 执行分页查询
        IPage<Article> page = this.page(pageInfo, wrapper);
        
        // 转换为VO对象
        IPage<ArticlePageVO> voPage = new Page<>();
        List<ArticlePageVO> voList = new ArrayList<>();
        
        for (Article article : page.getRecords()) {
            ArticlePageVO vo = new ArticlePageVO();
            BeanUtil.copyProperties(article, vo);
            
            // 获取分类信息
            Category category = categoryService.getById(article.getCategoryId());
            if (category != null) {
                vo.setCategoryName(category.getName());
                vo.setCategoryId(category.getId());
            }
            
            // 获取标签信息
            List<Tag> tags = articleMapper.getTagListByArticleId(article.getId());
            vo.setTags(tags);
            
            // 处理封面URL
            String titleImage = article.getTitleImage();
            if (titleImage != null && !titleImage.isEmpty()) {
                // 如果URL不是以http开头，则添加前缀
                if (!titleImage.startsWith("http://") && !titleImage.startsWith("https://")) {
                    titleImage = tencentCosConfig.getBaseUrl() + (tencentCosConfig.getBaseUrl().endsWith("/") ? "" : "/") + titleImage;
                }
                vo.setCover(titleImage);
                log.info("设置标签文章列表封面 - ID: {}, 最终URL: {}", article.getId(), titleImage);
            } else {
                // 不设置默认图片，前端会处理
                vo.setCover("");
                log.info("标签文章列表无封面 - ID: {}", article.getId());
            }
            
            voList.add(vo);
        }
        
        voPage.setRecords(voList);
        voPage.setTotal(page.getTotal());
        voPage.setCurrent(page.getCurrent());
        voPage.setSize(page.getSize());
        
        return voPage;
    }

}
